home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_300
/
365_01
/
curses.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
23KB
|
1,025 lines
/* curses.c */
/* Author:
* Steve Kirkendall
* 14407 SW Teal Blvd. #C
* Beaverton, OR 97005
* kirkenda@cs.pdx.edu
*/
/* This file contains the functions & variables needed for a tiny subset of
* curses. The principle advantage of this version of curses is its
* extreme speed. Disadvantages are potentially larger code, few supported
* functions, limited compatibility with full curses, and only stdscr.
*/
#include "config.h"
#include "vi.h"
#if ANY_UNIX
# if UNIXV
# ifdef TERMIOS
# include <termios.h>
# else
# include <termio.h>
# endif
# ifdef S5WINSIZE
# include <sys/stream.h> /* winsize struct defined in one of these? */
# include <sys/ptem.h>
# else
# undef TIOCGWINSZ /* we can't handle it correctly yet */
# endif
# else
# include <sgtty.h>
# endif
#endif
#if TOS
# include <osbind.h>
#endif
#if OSK
# include <sgstat.h>
#endif
#if VMS
extern int VMS_read_raw; /* Set in initscr() */
#endif
extern char *getenv();
static void starttcap();
/* variables, publicly available & used in the macros */
char *termtype; /* name of terminal entry */
short ospeed; /* speed of the tty, eg B2400 */
#if OSK
char PC_; /* Pad char */
char *BC; /* backspace character string */
#else
char PC; /* Pad char */
#endif
WINDOW *stdscr; /* pointer into kbuf[] */
WINDOW kbuf[KBSIZ]; /* a very large output buffer */
int LINES; /* :li#: number of rows */
int COLS; /* :co#: number of columns */
int AM; /* :am: boolean: auto margins? */
int PT; /* :pt: boolean: physical tabs? */
char *VB; /* :vb=: visible bell */
char *UP; /* :up=: move cursor up */
char *SO = ""; /* :so=: standout start */
char *SE = ""; /* :se=: standout end */
char *US = ""; /* :us=: underline start */
char *UE = ""; /* :ue=: underline end */
char *MD = ""; /* :md=: bold start */
char *ME = ""; /* :me=: bold end */
char *AS = ""; /* :as=: alternate (italic) start */
char *AE = ""; /* :ae=: alternate (italic) end */
#ifndef NO_VISIBLE
char *MV; /* :mv=: "visible" selection start */
#endif
char *CM; /* :cm=: cursor movement */
char *CE; /* :ce=: clear to end of line */
char *CD; /* :cd=: clear to end of screen */
char *AL; /* :al=: add a line */
char *DL; /* :dl=: delete a line */
#if OSK
char *SR_; /* :sr=: scroll reverse */
#else
char *SR; /* :sr=: scroll reverse */
#endif
char *KS = ""; /* :ks=: init string for cursor */
char *KE = ""; /* :ke=: restore string for cursor */
char *KU; /* :ku=: key sequence sent by up arrow */
char *KD; /* :kd=: key sequence sent by down arrow */
char *KL; /* :kl=: key sequence sent by left arrow */
char *KR; /* :kr=: key sequence sent by right arrow */
char *HM; /* :HM=: key sequence sent by the <Home> key */
char *EN; /* :EN=: key sequence sent by the <End> key */
char *PU; /* :PU=: key sequence sent by the <PgUp> key */
char *PD; /* :PD=: key sequence sent by the <PgDn> key */
char *KI; /* :kI=: key sequence sent by the <Insert> key */
#ifndef NO_FKEY
char *FKEY[NFKEYS]; /* :k0=: ... :k9=: sequences sent by function keys */
#endif
char *IM = ""; /* :im=: insert mode start */
char *IC = ""; /* :ic=: insert the following character */
char *EI = ""; /* :ei=: insert mode end */
char *DC; /* :dc=: delete a character */
char *TI = ""; /* :ti=: terminal init */ /* GB */
char *TE = ""; /* :te=: terminal exit */ /* GB */
#ifndef NO_CURSORSHAPE
#if 1
char *CQ = (char *)0;/* :cQ=: normal cursor */
char *CX = (char *)1;/* :cX=: cursor used for EX command/entry */
char *CV = (char *)2;/* :cV=: cursor used for VI command mode */
char *CI = (char *)3;/* :cI=: cursor used for VI input mode */
char *CR = (char *)4;/* :cR=: cursor used for VI replace mode */
#else
char *CQ = ""; /* :cQ=: normal cursor */
char *CX = ""; /* :cX=: cursor used for EX command/entry */
char *CV = ""; /* :cV=: cursor used for VI command mode */
char *CI = ""; /* :cI=: cursor used for VI input mode */
char *CR = ""; /* :cR=: cursor used for VI replace mode */
#endif
#endif
char *aend = ""; /* end an attribute -- either UE or ME */
char ERASEKEY; /* backspace key taken from ioctl structure */
#ifndef NO_COLOR
char normalcolor[16];
char SOcolor[16];
char SEcolor[16];
char UScolor[16];
char UEcolor[16];
char MDcolor[16];
char MEcolor[16];
char AScolor[16];
char AEcolor[16];
# ifndef NO_POPUP
char POPUPcolor[16];
# endif
# ifndef NO_VISIBLE
char VISIBLEcolor[16];
# endif
#endif
#if ANY_UNIX
# if UNIXV
# ifdef TERMIOS
static struct termios oldtermio; /* original tty mode */
static struct termios newtermio; /* cbreak/noecho tty mode */
# else
static struct termio oldtermio; /* original tty mode */
static struct termio newtermio; /* cbreak/noecho tty mode */
# endif
# else
static struct sgttyb oldsgttyb; /* original tty mode */
static struct sgttyb newsgttyb; /* cbreak/nl/noecho tty mode */
static int oldint; /* ^C or DEL, the "intr" character */
# ifdef TIOCSLTC
static int oldswitch; /* ^Z, the "suspend" character */
static int olddswitch; /* ^Y, the "delayed suspend" char */
static int oldquote; /* ^V, the "quote next char" char */
# endif
# endif
#endif
#if OSK
static struct sgbuf oldsgttyb; /* orginal tty mode */
static struct sgbuf newsgttyb; /* noecho tty mode */
#endif
static char *capbuf; /* capability string buffer */
/* Initialize the Curses package. */
void initscr()
{
/* make sure TERM variable is set */
termtype = getenv("TERM");
#if VMS
/* VMS getenv() handles TERM as a environment setting. Foreign
* terminal support can be implemented by setting the ELVIS_TERM
* logical or symbol to match a tinytcap entry.
*/
if (!strcmp(termtype,"unknown"))
termtype = getenv("ELVIS_TERM");
#endif
#if MSDOS
/* For MS-DOS, if TERM is unset we can default to "pcbios", or
* maybe "rainbow".
*/
if (!termtype)
{
#ifdef RAINBOW
if (*(unsigned char far*)(0xffff000eL) == 6 /* Rainbow 100a */
|| *(unsigned char far*)(0xffff000eL) == 148)/* Rainbow 100b */
{
termtype = "rainbow";
}
else
#endif
termtype = "pcbios";
}
if (!strcmp(termtype, "pcbios"))
#else
if (!termtype)
#endif
{
#if ANY_UNIX
write(2, "Environment variable TERM must be set\n", (unsigned)38);
exit(1);
#endif
#if OSK
writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
exit(1);
#endif
#if AMIGA
termtype = TERMTYPE;
starttcap(termtype);
#endif
#if MSDOS
starttcap("pcbios");
#endif
#if TOS
termtype = "vt52";
starttcap(termtype);
#endif
#if VMS
write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
exit(1);
#endif
}
else
{
#if MSDOS
*o_pcbios = 0;
#endif
/* start termcap stuff */
starttcap(termtype);
}
/* create stdscr and curscr */
stdscr = kbuf;
/* change the terminal mode to cbreak/noecho */
#if ANY_UNIX
# if UNIXV
# ifdef TERMIOS
tcgetattr(2, &oldtermio);
# else
ioctl(2, TCGETA, &oldtermio);
# endif
# else
ioctl(2, TIOCGETP, &oldsgttyb);
# endif
#endif
#if OSK
_gs_opt(0, &oldsgttyb);
#endif
#if VMS
VMS_read_raw = 1; /* cbreak/noecho */
vms_open_tty();
#endif
resume_curses(TRUE);
}
/* Shut down the Curses package. */
void endwin()
{
/* change the terminal mode back the way it was */
suspend_curses();
#if AMIGA
amiclosewin();
#endif
}
static int curses_active = FALSE;
/* Send any required termination strings. Turn off "raw" mode. */
void suspend_curses()
{
#if ANY_UNIX && !UNIXV
struct tchars tbuf;
# ifdef TIOCSLTC
struct ltchars ltbuf;
# endif
#endif
#ifndef NO_CURSORSHAPE
if (has_CQ)
{
do_CQ();
}
#endif
if (has_TE) /* GB */
{
do_TE();
}
if (has_KE)
{
do_KE();
}
#ifndef NO_COLOR
quitcolor();
#endif
refresh();
/* change the terminal mode back the way it was */
#if ANY_UNIX
# if UNIXV
# if TERMIOS
tcsetattr(2, TCSADRAIN, &oldtermio);
# else
ioctl(2, TCSETAW, &oldtermio);
# endif
# else
ioctl(2, TIOCSETP, &oldsgttyb);
ioctl(2, TIOCGETC, (struct sgttyb *) &tbuf);
tbuf.t_intrc = oldint;
ioctl(2, TIOCSETC,